#ifndef _BIB_DISCO_H
#define _BIB_DISCO_H

#include <stdlib.h>
#include <math.h>
#include <string.h>

#include <stdint.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/mman.h>

#include "bib_Log.h"
#include "bib_Abrir_Configuracion.h"
#include "bib_Socket.h"

typedef struct EST_CHS{	/*Todos tienen un valor minimo de cero para definir una posicion y un valor minimo de uno para definir el tamanio del disco*/
	uint16_t	cilindro;
	uint16_t	cabezal;
	uint16_t	sector;
} EST_CHS;

/*Algoritmos planificacion*/
#define SSTF	1
#define CLOOK	2

#define TAM_SECTOR 512

typedef struct EST_DISCO{
	struct EST_CHS	chs;
	unsigned int	tiempoLectura;
	unsigned int	tiempoEscritura;
	double			tiempoEntreSectores;
	unsigned int	tiempoEntrePistas;
	char			planificador;
} EST_DISCO;

typedef struct PAYLOAD_LECTURA{
	uint32_t	id;
	uint32_t	sector;
} PAYLOAD_LECTURA;

typedef struct PAYLOAD_RESPUESTA_LECTURA{
	uint32_t	id;
	char		buffer[TAM_SECTOR];
} PAYLOAD_RESPUESTA_LECTURA;

typedef struct PAYLOAD_ESCRITURA{
	uint32_t	id;
	uint32_t	sector;
	char		buffer[TAM_SECTOR];
} PAYLOAD_ESCRITURA;

typedef struct EST_PEDIDOS{
	uint32_t			id;
	char				tipo;	/*lectura, escritura, prueba*/
	uint32_t			sector;
	int					sock;
	char				*buffer;	/*puntero si es para escritura, NULL para otro*/
	struct EST_PEDIDOS	*siguiente;
} EST_PEDIDOS;

typedef struct EST_PLANIFICACION{
	/*uint16_t	cantSectoresDisco;*/
	uint16_t	tamanioCola;
	uint16_t	cantSectoresRecorridos;
	uint32_t	posicionActual;
	uint32_t	sectorSolicitado;
	double		tiempoConsumido;
	uint32_t	proximoSector;
} EST_PLANIFICACION;

#define LECTURA			1
#define ESCRITURA		2
#define PRUEBA			3
#define CANT_SECT		4
#define POSICION		5
#define SALIR			6
#define FIN_ESPEJADO	7
#define RTA_ERROR		10

/*Solo sirven en el caso de tener un solo cabezal*/
uint16_t distancia(uint16_t nro1, uint16_t nro2);

int deFisicaALogica(uint32_t *direccionLogica, struct EST_CHS chs);
int deLogicaAFisica(uint32_t direccionLogica, struct EST_CHS *chs);

int agregarPedido(uint32_t id, char tipo, uint32_t sector, int sock, char *buffer);
int sacarPedido(struct EST_PEDIDOS *pedidoAnterior, uint32_t *id, char *tipo, uint32_t *sector, int *sock, char **buffer);
int sacarPedidoSSTF(struct EST_PEDIDOS **pedidoAnterior);
int sacarPedidoCLOOK(struct EST_PEDIDOS **pedidoAnterior);

int seekTime(uint16_t cilindroDestino, unsigned long *tiempoConsumido, struct EST_CHS *poscFinal);
int recorridoSeekTime(uint16_t cilindroDestino, unsigned long *tiempoConsumido, uint32_t **sectoresRecorridos, uint16_t *cantPistasRecorridas);
int rotationalDelay(uint16_t sectorDestino, double *tiempoConsumido);

int atenderPedido(void);

#endif	/*_BIB_DISCO_H*/
